package com.nariano.server.services.cityservice.impl;

import java.util.List;
import java.util.logging.Logger;

import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Expression;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.nariano.server.domain.entities.Area;
import com.nariano.server.domain.entities.City;
import com.nariano.server.domain.entities.Location;
import com.nariano.server.domain.entities.User;
import com.nariano.server.services.cityservice.CityService;
import com.nariano.server.services.mapservice.MapService;

@Transactional
public class CityServiceImpl implements CityService {

    private SessionFactory sessionFactory;
    
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }
	
    private Logger logger = Logger.getLogger(CityServiceImpl.class.getCanonicalName());
    
    
    public List<City> getCities() {
        return getHibernateTemplate().loadAll(City.class);
    }
    
    public List<City> getCities(User user) {
        DetachedCriteria dc = DetachedCriteria.forClass(City.class);
        dc.add(Expression.eq("owner", user));
        List list = getHibernateTemplate().findByCriteria(dc);
        return list;
    }
    
    public City getCity(Location location) {
        Area area = findArea(location);
        City city = area==null ? null : area.getCity();
        logger.fine(""+ city);
        return city;
    }

    private Area findArea(Location location) {
        DetachedCriteria dc = DetachedCriteria.forClass(Area.class);
        dc.add(Expression.eq("location", location));
        List list = getHibernateTemplate().findByCriteria(dc);
        if (list.isEmpty()) { return null; }
        Assert.isTrue(1 == list.size(), "Java datamodel not compliant with db-model: " + list.size());
        return (Area) list.get(0);
    }

    public List<City> findCity(String name) {
        DetachedCriteria dc = DetachedCriteria.forClass(City.class);
        dc.add(Expression.eq("name", name));
        List list = getHibernateTemplate().findByCriteria(dc);
        return list;
    }

    private HibernateTemplate getHibernateTemplate() {
        return new HibernateTemplate(sessionFactory);
    }

	public void updateCity(City city) {
		Assert.notNull(city.getId(),"Tried to update a city that has not been created");
		getHibernateTemplate().saveOrUpdate(city);
	}

}
